package com.like.hospitalworld;

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;

import com.like.entity.Department;
import com.like.entity.EventWrapper;
import com.like.entity.GeneralResponse;
import com.like.entity.OpenTokenReq;
import com.like.entity.OpenTokenResp;
import com.like.fragment.MainDocumentFragment;
import com.like.fragment.MainInformationFragment;
import com.like.fragment.MainMeetingFragment;
import com.like.fragment.MainWindowFragment;
import com.like.likeutils.network.RetrofitCallback;
import com.like.network.AESInterceptor;
import com.like.network.AuthService;
import com.like.network.RetrofitUtil;
import com.like.network.TokenInterceptor;
import com.like.utils.AppUtils;
import com.like.utils.Constants;
import com.like.widget.MyToast;
import com.nineoldandroids.animation.ValueAnimator;
import com.nineoldandroids.view.ViewHelper;

import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import org.xutils.view.annotation.ContentView;
import org.xutils.view.annotation.Event;
import org.xutils.view.annotation.ViewInject;

import java.util.List;

import retrofit2.Call;
import retrofit2.Response;

@ContentView(R.layout.activity_main)
public class MainActivity extends BaseActivity {

    public static final String TAG_TOP_TAB_CHANGE = "top_tab_change";

    @ViewInject(R.id.tab_info_container)
    private ViewGroup mTabInfo;
    @ViewInject(R.id.tab_window_container)
    private ViewGroup mTabWindow;
    @ViewInject(R.id.tab_meeting_container)
    private ViewGroup mTabMeeting;
    @ViewInject(R.id.tab_document_container)
    private ViewGroup mTabDocument;
    @ViewInject(R.id.toolbar_container)
    private ViewGroup mToolbarContainer;
    @ViewInject(R.id.top_tab_container)
    private ViewGroup mTopTabContainer;
    @ViewInject(R.id.index_indicator)
    private ViewGroup mIndexIndicator;

    @ViewInject(R.id.pediatrics)
    ViewGroup mTabPediatrics;
    @ViewInject(R.id.internal_medicine)
    ViewGroup mTabInternalMedicine;
    @ViewInject(R.id.dermatology)
    ViewGroup mTabDermatology;
    @ViewInject(R.id.others)
    ViewGroup mTabOthers;

    private Fragment[] mFragments;
    private ViewGroup[] mTabs;
    private ViewGroup[] mTopTabs;
    private int mToolbarHeight = 0;
    private int mTopTabHeight = 0;
    private float mDownY = 0;
    private List<Department> mAllDeps;
    private AuthService mAuthService;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        EventBus.getDefault().register(this);
        mAuthService = RetrofitUtil.getService(AuthService.class);
        initTabs();
        initTopTabs();
        mAllDeps = m.getAllDeps();
        mTopTabContainer.post(new Runnable() {
            @Override
            public void run() {
                mToolbarHeight = mToolbarContainer.getHeight();
                mTopTabHeight = mTopTabContainer.getHeight();
                ViewHelper.setY(mTopTabContainer, -mTopTabHeight);
                if (m.getCurrentDep() == null) {
                    slideDown();
                    mIndexIndicator.setVisibility(View.VISIBLE);
                } else
                    mIndexIndicator.setVisibility(View.GONE);
            }
        });
        changeTopTab(m.getCurrentDep());
        mToolbarContainer.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                float y = event.getY();
                switch (event.getAction()) {
                    case MotionEvent.ACTION_DOWN:
                        mDownY = event.getY();
                        if (mTopTabContainer.getY() >= mToolbarHeight) {
                            slideUp();
                            return false;
                        }
                        break;
                    case MotionEvent.ACTION_MOVE:
                        if (y >= mTopTabHeight + mToolbarHeight)
                            ViewHelper.setY(mTopTabContainer, mToolbarHeight);
                        else
                            ViewHelper.setY(mTopTabContainer, y - mTopTabHeight);
                        break;
                    case MotionEvent.ACTION_UP:
                        float upY = event.getY();
                        if (upY - mDownY < 5) {
                            if (mTopTabContainer.getY() < 3) {
                                slideDown();
                                return false;
                            }
                        }
                        if (mTopTabContainer.getY() > mToolbarHeight / 3)
                            slideDown();
                        else
                            slideUp();
                        break;
                }
                return true;
            }
        });
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        EventBus.getDefault().unregister(this);
    }

    @Subscribe
    public void getEvent(EventWrapper event) {
        if (EventWrapper.isMatch(event, AESInterceptor.TAG_REFRESH_TOKEN)) {
            getToken();
        }
        if(EventWrapper.isMatch(event, PersonalCenterActivity.LOG_OUT)) {
            finish();
        }
    }

    private void getToken() {
        OpenTokenReq req = new OpenTokenReq(Constants.PID, Constants.PROJECT_ID, AppUtils.getDeviceId(m.mContext));
        Call<GeneralResponse<OpenTokenResp>> call = mAuthService.openToken(Constants.PID, Constants.PROJECT_ID, req);
        call.enqueue(new RetrofitCallback<GeneralResponse<OpenTokenResp>>() {
            @Override
            public void onResponse(Call<GeneralResponse<OpenTokenResp>> call, Response<GeneralResponse<OpenTokenResp>> response) {
                if (!response.isSuccessful())
                    return;
                String token = response.body().data.token;
                m.setToken(token);
            }

            @Override
            public void onFailure(Call<GeneralResponse<OpenTokenResp>> call, Throwable t) {
            }
        });
    }

    private void slideUp() {
        ValueAnimator animator = ValueAnimator.ofFloat(mTopTabContainer.getY(), -mTopTabHeight).setDuration(500);
        animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                float value = (float) animation.getAnimatedValue();
                ViewHelper.setY(mTopTabContainer, value);
            }
        });
        animator.start();
    }

    private void slideDown() {
        ValueAnimator animator = ValueAnimator.ofFloat(mTopTabContainer.getY(), mToolbarHeight).setDuration(500);
        animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                float value = (float) animation.getAnimatedValue();
                ViewHelper.setY(mTopTabContainer, value);
            }
        });
        animator.start();
    }

    private void initTabs() {
        MainInformationFragment indexFragment = new MainInformationFragment();
        indexFragment.setIsIndex(true);
        MainInformationFragment infoFragment = new MainInformationFragment();
        infoFragment.setIsIndex(false);
        MainWindowFragment windowFragment = new MainWindowFragment();
        MainMeetingFragment meetingFragment = new MainMeetingFragment();
        MainDocumentFragment documentFragment = new MainDocumentFragment();
        mFragments = new Fragment[]{indexFragment, infoFragment, windowFragment, meetingFragment, documentFragment};
        mTabs = new ViewGroup[]{mTabInfo, mTabWindow, mTabMeeting, mTabDocument};
        changeTab(0);
    }

    private void initTopTabs() {
        mTopTabs = new ViewGroup[]{mTabPediatrics, mTabInternalMedicine, mTabDermatology, mTabOthers};
    }

    @Event({R.id.tab_info_container, R.id.tab_window_container, R.id.tab_meeting_container, R.id.tab_document_container})
    private void tabClick(View v) {
        if (m.getCurrentDep() == null) {
            MyToast.showBlueCircleToast(m.mContext, "请选择科室");
            return;
        }
        switch (v.getId()) {
            case R.id.tab_info_container:
                changeTab(1);
                break;
            case R.id.tab_window_container:
                changeTab(2);
                break;
            case R.id.tab_meeting_container:
                changeTab(3);
                break;
            case R.id.tab_document_container:
                changeTab(4);
                break;
        }
    }

    @Event({R.id.pediatrics, R.id.internal_medicine, R.id.dermatology, R.id.others})
    private void topTabClick(View v) {
        if (mIndexIndicator.getVisibility() == View.VISIBLE)
            mIndexIndicator.setVisibility(View.GONE);
        switch (v.getId()) {
            case R.id.pediatrics:
                changeTopTab(1);
                break;
            case R.id.internal_medicine:
                changeTopTab(2);
                break;
            case R.id.dermatology:
                changeTopTab(3);
                break;
            case R.id.others:
                changeTopTab(4);
                break;
        }
        changeTab(0);
        slideUp();
    }

    private void changeTopTab(Department dep) {
        if (dep == null)
            return;
        if (dep.name.equals("儿科"))
            changeTopTab(1);
        else if (dep.name.equals("内科"))
            changeTopTab(2);
        else if (dep.name.equals("皮科"))
            changeTopTab(3);
        else if (dep.name.equals("其他"))
            changeTopTab(4);
    }

    private void changeTopTab(int position) {
        if (position == 0)
            return;
        position -= 1;
        for (ViewGroup tab : mTopTabs)
            setTopTabSelected(tab, false);
        setTopTabSelected(mTopTabs[position], true);
        m.setCurrentDep(mAllDeps.get(position));
        EventBus.getDefault().post(new EventWrapper(mAllDeps.get(position), TAG_TOP_TAB_CHANGE));
    }

    private void setTopTabSelected(ViewGroup tab, boolean selected) {
        tab.setSelected(selected);
        for (int i = 0; i < tab.getChildCount(); i++)
            tab.getChildAt(i).setSelected(selected);
    }

    private void changeTab(int position) {
        for (int i = 0; i < mTabs.length; i++)
            setTabSelected(i, false);
        if (position != 0)
            setTabSelected(position - 1, true);
        setFragmentSelected(position);
    }

    public View setToolbar(int resourceId) {
        mToolbarContainer.removeAllViews();
        View contentView = LayoutInflater.from(m.mContext).inflate(resourceId, null, false);
        mToolbarContainer.addView(contentView);
        return contentView;
    }

    private void setFragmentSelected(int position) {
        for (int i = 0; i < mFragments.length; i++) {
            if (mFragments[i].isAdded() && mFragments[i].isVisible())
                getSupportFragmentManager().beginTransaction().hide(mFragments[i]).commit();
        }
        Fragment fragment = mFragments[position];
        if (!fragment.isAdded())
            getSupportFragmentManager().beginTransaction().add(R.id.main_container, fragment).commit();
        else
            getSupportFragmentManager().beginTransaction().show(fragment).commit();
    }

    private void setTabSelected(int position, boolean selected) {
        ViewGroup tab = mTabs[position];
        for (int i = 0; i < tab.getChildCount(); i++) {
            View v = tab.getChildAt(i);
            v.setSelected(selected);
        }
    }
}
